/* Copyright(C) 2006-2008 Dave Sexton  *
 * http://www.codeplex.com/aip         *
 * http://www.codeplex.com/aip/license *
 ***************************************/
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Configuration.Provider;
using DaveSexton.Web.Controls.Resources;

namespace DaveSexton.Web.Controls
{
	/// <summary>
	/// An implementation of <see cref="AutoInputProtectionImageProvider"/> that derives from <see cref="PartitionedAutoInputProtectionImageProvider"/>
	/// for creating instances of <see cref="LineNoiseAutoInputProtectionImage"/>, which renders randomized line segments on a white surface image.
	/// This class cannot be inherited.
	/// </summary>
	/// <remarks>
	/// <para>
	/// <see cref="LineNoiseAutoInputProtectionImageProvider"/> is the default image provider that is used when no image providers are configured.
	/// </para>
	/// <para>
	/// <see cref="LineNoiseAutoInputProtectionImageProvider"/> is a factory that creates instances of <see cref="LineNoiseAutoInputProtectionImage"/>.
	/// Each instance is initialized with the list of <see cref="Colors"/> from which random samples are taken to create randomized line segments, on a 
	/// white surface image.
	/// </para>
	/// </remarks>
	/// <include file='examples.xml' path='//example[@id="LineNoise"][@type="images"]'/>
	/// <include file='examples.xml' path='//example[@id="LineNoise"][@type="config"]'/>
	/// <seealso cref="AutoInputProtection.DefaultImageProvider"/>
	/// <seealso cref="Configuration.AutoInputProtectionSection"/>
	/// <seealso cref="AutoInputProtectionTextProvider"/>
	/// <seealso cref="AutoInputProtectionFilterProvider"/>
	/// <seealso cref="LineNoiseAutoInputProtectionImage"/>
	public sealed class LineNoiseAutoInputProtectionImageProvider : PartitionedAutoInputProtectionImageProvider	// derived after 1.0.0 RTW
	{
		#region Public Properties
		/// <summary>
		/// Gets a list of <see cref="Color">Colors</see> from which one will be sampled at random by an instance of 
		/// <see cref="LineNoiseAutoInputProtectionImage"/> and used to draw a single randomized line segment.
		/// </summary>
		/// <remarks>
		/// <para>
		/// At least one <see cref="Color"/> must be specified or else the <see cref="LineNoiseAutoInputProtectionImage.CreateSurfaceImage"/> method will throw 
		/// an <see cref="InvalidOperationException"/>.
		/// </para>
		/// <para>
		/// By default, <see cref="Color.Black"/> is used by <see cref="LineNoiseAutoInputProtectionImage"/> if no colors are configured for the provider.
		/// </para>
		/// </remarks>
		/// <value>List of <see cref="Color">Colors</see> from which one will be sampled at random by an instance of 
		/// <see cref="LineNoiseAutoInputProtectionImage"/> and used to draw a single randomized line segment.</value>
		public IList<Color> Colors
		{
			get
			{
				return colors;
			}
		}
		#endregion

		#region Private / Protected
		private readonly List<Color> colors = new List<Color>(8);
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="LineNoiseAutoInputProtectionImageProvider" /> class.
		/// </summary>
		public LineNoiseAutoInputProtectionImageProvider()
		{
		}
		#endregion

		#region Methods
		/// <summary>
		/// Loads the provider's settings from the specified <paramref name="config"/>.
		/// </summary>
		/// <exception cref="ProviderException">An attribute value cannot be converted into the required type.</exception>
		/// <param name="name">Name of the provider.</param>
		/// <param name="config">A collection of name and value pairs that will be used to initialize the provider.</param>
		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			if (config == null)
				throw new ArgumentNullException("config");

			if (String.IsNullOrEmpty(name))
				name = "LineNoiseAutoInputProtectionImageProvider";

			if (string.IsNullOrEmpty(config["description"]))
			{
				config.Remove("description");
				config.Add("description", "Line Noise Auto-Input Protection Image Provider");
			}

			ProviderHelper helper = new ProviderHelper(config);

			colors.AddRange(helper.ParseCollection<Color>("colors", false, true, false, ','));

			base.Initialize(name, config);

			// Throw an exception if unrecognized attributes remain
			if (config.Count > 0)
			{
				string attr = config.GetKey(0);

				if (!String.IsNullOrEmpty(attr))
					throw new ProviderException(string.Format(System.Globalization.CultureInfo.CurrentUICulture,
						Errors.UnrecognizedAttribute, attr));
			}
		}

		/// <summary>
		/// Creates an instance of a <see cref="LineNoiseAutoInputProtectionImage"/> for the specified <paramref name="size"/> 
		/// and <paramref name="textProvider"/>.
		/// </summary>
		/// <seealso cref="AutoInputProtection.GenerateAutoInputProtectionImage"/>
		/// <seealso cref="GenerateAutoInputProtectionImage"/>
		/// <param name="size">The dimensions of the image.</param>
		/// <param name="textProvider"><see cref="AutoInputProtectionTextProvider"/> implementation to be used by the 
		/// <see cref="LineNoiseAutoInputProtectionImage"/> that is created.</param>
		/// <returns>An instance of <see cref="LineNoiseAutoInputProtectionImage"/> that can generate an image of the specified <paramref name="size"/> using 
		/// the specified <paramref name="textProvider"/>.</returns>
		public override AutoInputProtectionImage GenerateRandomAutoInputProtectionImage(Size size, AutoInputProtectionTextProvider textProvider)
		{
			return GenerateAutoInputProtectionImage(null, size, textProvider);
		}

		/// <summary>
		/// Creates an instance of a <see cref="LineNoiseAutoInputProtectionImage"/> for the specified <paramref name="size"/> 
		/// and <paramref name="textProvider"/>.
		/// </summary>
		/// <remarks>
		/// The specified <paramref name="name"/> will be ignored.  The same result can be obtained by calling the
		/// <see cref="GenerateRandomAutoInputProtectionImage(Size,AutoInputProtectionTextProvider)"/> overload instead.
		/// </remarks>
		/// <seealso cref="AutoInputProtection.GenerateAutoInputProtectionImage"/>
		/// <seealso cref="GenerateRandomAutoInputProtectionImage"/>
		/// <param name="name">Not used.</param>
		/// <param name="size">The dimensions of the image.</param>
		/// <param name="textProvider"><see cref="AutoInputProtectionTextProvider"/> implementation to be used by the 
		/// <see cref="LineNoiseAutoInputProtectionImage"/> that is created.</param>
		/// <returns>An instance of <see cref="LineNoiseAutoInputProtectionImage"/> that can generate an image of the specified <paramref name="size"/> using 
		/// the specified <paramref name="textProvider"/>.</returns>
		public override AutoInputProtectionImage GenerateAutoInputProtectionImage(string name, Size size, AutoInputProtectionTextProvider textProvider)
		{
			LineNoiseAutoInputProtectionImage image = new LineNoiseAutoInputProtectionImage(size, textProvider, colors);

			// code added after 1.0.0 RTW: 
			if (Margin != -1)
				image.Margin = Margin;

			if (MinimumCharacterRotation != -1)
				image.MinimumCharacterRotation = MinimumCharacterRotation;

			if (MaximumCharacterRotation != -1)
				image.MaximumCharacterRotation = MaximumCharacterRotation;

			return image;
		}
		#endregion
	}
}